<?php
/**
 * TreeStructure
 *
 * Класс для работы с древовидной структурой
 *
 */
class TreeStructure{

	public $arrFolders = array();//масси для преобразований

        public static function getTreeStructureBBB($essenceType, $linearFlag = false, $idUser = NULL, $linearForCurFoldersInArray = false, $arrCurFoldersIds = array()){
                $objDB = Service_Database::instance();
//              $essenceType = Service_Essence::getEssenceTypeName(Service_Essence::getEssenceTypeID($essenceType));
                $stmt = 'SELECT `folder`.`ID_folder`, `folder`.`ID_root_folder`, `folder`.`name` AS `folder_name`,
                                `folder`.`ID_user`, `folder`.`ID_main_root_folder`, `folder`.`description`, `folder`.`creation`,
                                `folder`.`average_mark`, `folder`.`mark_amount`, `folder`.`children_amount`, `folder`.`show_folder`, `folder`.`parents_ids`, `folder`.`closed_at_start`';
                switch ($essenceType){
                        case 'question':
                                $stmt .= ', `folder`.`' . $essenceType . '_amount`, `folder`.`question_amount` FROM `folder`'; break;
                        case 'solution':
                                $stmt .= ', `folder`.`' . $essenceType . '_amount`
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                        case 'tutorial':
                                $stmt .= ', `folder`.`' . $essenceType . '_amount`, `tutorial`.`ID_tutorial`, `tutorial`.`name`, `tutorial`.`url_name`
                                                FROM `folder`
                                                LEFT JOIN `tutorial`
                                                ON `tutorial`.`ID_folder` = `folder`.`ID_folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                        case 'programming_language':
                                $stmt .= ', `folder`.`' . $essenceType . '_amount`, `programming_language`.`ID_language` AS `ID_programming_language`, `programming_language`.`language` AS `name`
                                                FROM `folder`
                                                LEFT JOIN `folder_link_language`
                                                ON `folder_link_language`.`ID_folder` = `folder`.`ID_folder`
                                                LEFT JOIN `programming_language`
                                                ON `programming_language`.`ID_language` = `folder_link_language`.`ID_language`

                                                WHERE `folder`.`show_folder` = 1'; break;
                        case 'community':
                                $stmt .= '
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                        case 'article':
                                $stmt .= ', `folder`.`' . $essenceType . '_amount`
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                        case 'content_request':
                        				$stmt .= ', `folder`.`' . $essenceType . '_amount`
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                        case 'empty':
                        				$stmt .= '      FROM `folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                        default:
                                $stmt .= ', `' . $essenceType . '`.`ID_' . $essenceType . '`, `' . $essenceType . '`.`name`
                                                FROM `folder`
                                                LEFT JOIN `' . $essenceType . '`
                                                ON `' . $essenceType . '`.`ID_folder` = `folder`.`ID_folder`
                                                WHERE `folder`.`show_folder` = 1'; break;
                }
                if ($linearFlag){
                        if (!$linearForCurFoldersInArray)
                                $arrFoldersIds = TreeStructure::getLinearFoldersListCurUser($idUser);
                        else
                                $arrFoldersIds = $arrCurFoldersIds;
                        if (sizeof($arrFoldersIds) == 0)
                                return array('arr_folder' => array(), 'folder_size' => 0);
                        if ($essenceType == 'question')
                                $stmt .= ' WHERE `folder`.`ID_folder` IN ("' . join('", "', $arrFoldersIds) . '")';

                        else
                                $stmt .= ' AND `folder`.`ID_folder` IN ("' . join('", "', $arrFoldersIds) . '")';
                }
                $arrFolderFromDB = $objDB->select($stmt);
                $size = sizeof($arrFolderFromDB);
                for ($i = 0; $i < $size; $i++){
                        $arrFolderFromDB[$i]['parents_ids'] = explode(', ', $arrFolderFromDB[$i]['parents_ids']);
                }
                switch ($essenceType){
                        case 'question':
                                $arrFolderFromDB = $arrFolderFromDB; break;
//                              $arrFolderFromDB = self::convertArrayForQuestion($arrFolderFromDB); break;
                        case 'solution':{
                                $arrFolderFromDB = $arrFolderFromDB;
                        } break;
                        case 'tutorial':{
                                $arrFields = array(0 => 'ID_tutorial', 1 => 'name', 2 => 'url_name');
                                $arrFolderFromDB = arrayConvert($arrFolderFromDB, 'ID_folder', $arrFields, 'array_tutorial');
                        } break;
                        case 'content_request':
                                $arrFolderFromDB = $arrFolderFromDB; break;
                        default:{
                                $arrFields = array(0 => 'ID_' . $essenceType, 1 => 'name');
                                $arrFolderFromDB = arrayConvert($arrFolderFromDB, 'ID_folder', $arrFields, 'array_' . $essenceType);
                        } break;
                }
                $folderSize = sizeof($arrFolderFromDB);
/*              echo '<pre>';
                //echo $stmt;

                print_r($arrFolderFromDB);
                echo '</pre>';*/
                if ($linearFlag)
                        return array('arr_folder' => $arrFolderFromDB, 'folder_size' => $folderSize);
                $arrFolder = Service_ArrayConverter::convertToTreeArray($arrFolderFromDB, 'ID_folder', 'ID_root_folder');
                return array('arr_folder' => $arrFolder, 'folder_size' => $folderSize);
        }

        private static function convertArrayForQuestion($arrFolders){
/*              echo '<pre style="font-size:16px;">';
                print_r($arrFolders);
                echo  '</pre><br />';*/

                $arrFoldersCount = sizeof($arrFolders);
                for ($i = 0; $i < $arrFoldersCount; $i++){
                        $idCurFolder = $arrFolders[$i]['ID_folder'];
                        for ($j = $i; $j < $arrFoldersCount; $j++){
                                if (isset($arrFolders[$j]['ID_root_folder']) && $arrFolders[$j]['ID_root_folder'] == $idCurFolder && isset($arrFolders[$j]['show_folder']) && $arrFolders[$j]['show_folder'] == 0){
                                        if (!isset($arrFolders[$i]['array_question']))
                                                $arrFolders[$i]['array_question'] = array();
                                        $arrFolders[$i]['array_question'][] = $arrFolders[$j];
                                        $arrFolders[$j] = NULL;
                                }
                        }
                }
/*              for ($i = 0; $i < $arrFoldersCount; $i++){
                        if (isset($arrFolders[$i]['ID_folder']) && $arrFolders[$i]['children_amount'] == 0){
                                if (!isset($arrFolders[$i]['array_question']))
                                        $arrFolders[$i]['array_question'] = array();
                                $arrFolders[$i]['array_question'][] = array(
                                'ID_folder' => $arrFolders[$i]['ID_folder'],
                                'folder_name' => 'Вопросы раздела "' . $arrFolders[$i]['folder_name'] . '"',
                                'question_amount' => $arrFolders[$i]['question_amount'],
                                'description' => $arrFolders[$i]['description']);
                        }
                }*/
                for ($i = 0; $i < $arrFoldersCount; $i++){
                        if ($arrFolders[$i] != NULL){
                                $arrFoldersNew[] = $arrFolders[$i];
                        }
                }
/*              echo '<pre style="font-size:16px;">';
                print_r($arrFoldersNew);
                echo  '</pre><br />';*/
                return $arrFoldersNew;
        }

        public static function getLinearFoldersListCurUser($idUser){
                $objDB = Service_Database::instance();
                $stmt = 'SELECT `users_folders`.`ID_folder`
                                FROM `users_folders`
                                WHERE `users_folders`.`ID_user` = ' . $idUser;
                return $objDB->selectSimpleArray($stmt);
        }

        /**
         * список любимых разделов пользователя с их именами
         *
         */
        public static function getUsersFoldersName($idUser){
                $objDB = Service_Database::instance();
                $stmt = '
                SELECT `users_folders`.`ID_folder`,
                                         `folder`.`name`
                FROM `users_folders`
                LEFT JOIN `folder` ON `folder`.`ID_folder` = `users_folders`.`ID_folder`
                WHERE `users_folders`.`ID_user` = ' . $idUser . ' AND
                                        `folder`.`show_folder` = 1';
                return $objDB->select($stmt);
        }

        private static function getCurFolderInfo($idFolder){
                $objDB = Service_Database::instance();
                $stmt = 'SELECT `folder`.`ID_folder`
                                FROM `folder`
                                WHERE `folder`.`ID_root_folder` = ' . $idFolder . '
                                AND `folder`.`show_folder` = 0';
                return $objDB->selectSimpleArray($stmt);
        }

        public static function getFolderInfo($idFolder){
                $objDB = Service_Database::instance();
                if (!$idFolder)
                        return array();
                $stmt = 'SELECT `folder`.`ID_folder`,
                                                                                `folder`.`ID_root_folder`,
                                                                                `folder`.`show_folder`,
                                                                                `folder`.`name`
                                FROM `folder`
                                WHERE `folder`.`ID_folder` = ' . $idFolder;
                return $objDB->selectOne($stmt);
        }
        
        public static function getFolderLangInfo($idFolder){
                $objDB = Service_Database::instance();
                if (!$idFolder)
                        return '';
                $stmt = 'SELECT `programming_language`.`language`
                         FROM `folder_link_language`
                         LEFT JOIN `programming_language` ON `programming_language`.`ID_language` = `folder_link_language`.`ID_language`
                         WHERE `folder_link_language`.`ID_folder` = ' . $idFolder;
                return $objDB->selectSimpleField($stmt);
        }        


        public static function addCurFolderToUser($arrFolders, $idUser){
                $objDB = Service_Database::instance();
                if (sizeof($arrFolders) != 0){
                        foreach ($arrFolders as $idFolder){
                                $arrInsert = array('ID_folder' => $idFolder, 'ID_user' => $idUser);
                                $arrFolderInfo = self::getFolderInfo($idFolder);
                                if($arrFolderInfo['show_folder'] != 0){
                                        $objDB->insert('users_folders', $arrInsert);
                                        self::setUsersCountForFolder($idFolder, true);
                                }
/*                              $arrFolderInfo = self::getCurFolderInfo($idFolder);
                                if (sizeof($arrFolderInfo) != 0){
                                        foreach ($arrFolderInfo as $idFolder){
                                                $arrInsert = array('ID_folder' => $idFolder, 'ID_user' => $idUser);
                                                $objDB->insert('users_folders', $arrInsert);
                                        }
                                }*/
                        }
                }
                else return false;
        }



        public static function getCurUsersFolderInfo($idFolder, $idUser){
                $objDB = Service_Database::instance();
                $stmt = 'SELECT `users_folders`.`ID_folder`
                                FROM `users_folders`
                                WHERE `users_folders`.`ID_folder` = ' . $idFolder . '
                                AND `users_folders`.`ID_user` = ' . $idUser;
                return $objDB->selectOne($stmt);
        }

        public static function deleteFoldersFromUser($arrFolders, $idUser){
                $objDB = Service_Database::instance();
                if (sizeof($arrFolders) != 0){
                        foreach ($arrFolders as $idFolder){
                                $arrWhere = array('ID_folder' => $idFolder, 'ID_user' => $idUser);
                                $objDB->delete('users_folders', $arrWhere);
                                self::setUsersCountForFolder($idFolder, false);
//                              $arrFolderInfo = self::getCurFolderInfo($idFolder);
/*                              if (sizeof($arrFolderInfo) != 0){
                                        foreach ($arrFolderInfo as $idFolder){
                                                $arrWhere = array('ID_folder' => $idFolder, 'ID_user' => $idUser);
                                                $objDB->delete('users_folders', $arrWhere);
                                        }
                                }*/
                        }
                }
                else return false;
        }

  /**
   * Проверяет, можно ли добавить в текущий раздел новый подраздел
   *
   * @param int $ID_folder
   * @return bool
   */
  public static function checkNewFolderCanBeAdded($ID_folder) {
    $arrCurFolder = self::getFolder($ID_folder);
    if (($arrCurFolder['name'] != 'Общие вопросы') && ($arrCurFolder['name'] != 'Другие вопросы'))
      return true;
    return false;
  }
 /**
   * Добавление нового логического раздела
   *
   * @param int $ID_user - идентификатор пользователя
   * @param string $name - название раздела
   * @param string $description - описание раздела
   * @param int $ID_root - идентификатор корневого раздела
   * @param array $arrCanAddEssence - массив с параметрами, указывающими, какие добавлять сущности вместе с разделом
   * tutorial, programmingLanguage
   * @return bool
   */
  public static function addFolder(int $ID_user, string $name, string $description, $ID_root = NULL, $arrCanAddEssence = array()){
/*  	echo '<pre>';
  	print_r($arrCanAddEssence);
  	echo '</pre>';*/
    if (!$ID_root || $ID_root == 'NULL' || $ID_root == 'NULL')
      $ID_root = NULL;
    //Проверяем, есть ли у раздела, в который добавляем подраздел другие подразделы, и если ещё нет, то добавляем доп. подразделы
    if (!self::checkNewFolderCanBeAdded($ID_root))
      throw new Exception('В этот раздел нельзя добавить подраздел');
    if (empty($name))
      throw new Exception('Вы не ввели название нового раздела');
    if ($ID_root && (self::_getCountOfChildrenFolders($ID_root) == 0)){
      $commonQuestionsIds = self::_baseAddFolder($ID_user, 'Общие вопросы', 'Общие вопросы для (под)раздела "' . self::getFolderName($ID_root) . '"', $ID_root, true);
      self::addChildrenForFolder($commonQuestionsIds, false);
      $questionsCnt = self::_baseMoveFolderQuestionsToFolder($ID_root, $commonQuestionsIds); //Кол-во перемещённых вопросов
      if ($questionsCnt > 0)
        for ($i=0; $i<$questionsCnt; $i++)
        	self::incrementStructureEssenceCnt($commonQuestionsIds, 'question', true);
      $ID_folder = self::_baseAddFolder($ID_user, 'Другие вопросы', 'Другие вопросы для (под)раздела "' . $name . '"', $ID_root, true);
      self::addChildrenForFolder($ID_folder, false);
    }
    $ID_folder = self::_baseAddFolder($ID_user, $name, $description, $ID_root);
    Community::insertCommunity($ID_folder, $ID_user);
    if (isset($arrCanAddEssence['tutorial']) and $arrCanAddEssence['tutorial']['canAdd']){
    	$objTutorial = new Tutorial();
    	$objTutorial->addTutorial($ID_folder, $name, $arrCanAddEssence['tutorial']['tutorial_name_for_link']);
    }
    if (isset($arrCanAddEssence['programmingLanguage']) and $arrCanAddEssence['programmingLanguage']['canAdd'])
    	Code::addLanguage($ID_folder, $arrCanAddEssence['programmingLanguage']['language_name_for_geshi']);

    Statistics::addEvent(99, $ID_user);//добавляем в статистику
    Rating::addRating($ID_folder, 16, $ID_user, 8, $ID_folder);
    if ($ID_root)
        self::addChildrenForFolder($ID_folder, true);
    return true;
  }

  /**
   * получение данных для построения дерева рейтинга пользователя
   *
   */
  public static function getUserRatingInTree($idUser = NULL, $arrPlaceFolder = NULL){
        //получаем id папок с рейтингом и их родителей
        if ($idUser){
	        $arrUserRatingFolder = self::getTopFoldersByUserRating($idUser);
	        if ($arrUserRatingFolder){
	                //создаем массив из папок с рейтингом
	                foreach ($arrUserRatingFolder as $arr)
	                        $arrUserRating[] = $arr['ID_folder'];
	
	                //получаем всё папки, нужные для построения дерева
	                $arrRatingForTreeConv = self::_baseGetFolderRatingCurUser($arrUserRatingFolder, $arrUserRating, $idUser);
	                //сортируем масив по возрастаюнию
	                sort($arrUserRating);
	                //вместо ключа задаем idfolder
	                foreach ($arrRatingForTreeConv as $arr=>$b)
	                        $arrayKeyId[$b['ID_folder']] = $b;
	
	                //дополняем массив данные из масива с местами пользоваля, создаем новый ключ 'place'
	                if ($arrPlaceFolder)
		                foreach ($arrPlaceFolder as $arr)
		                	if (isset($arrayKeyId[$arr['ID_folder']]))
		                		$arrayKeyId[$arr['ID_folder']]['place'] = $arr['place'];
	
	                //прибавляем рейтинг потомков родительским папкам
	                foreach ($arrUserRating as $arr=>$id)
	                        $arrayKeyId = self::updateParrentsRating($id, $arrayKeyId, $arrayKeyId[$id]['rating']);
	
	
	                //создем массив со сквозной нумирацией ключей для последующего преобразования в дерево
	                foreach ($arrayKeyId as $a)
	                        $arraySortedWithRating[] = $a;
	
	                $arrTree = Service_ArrayConverter::convertToTreeArray($arraySortedWithRating, 'ID_folder', 'ID_root_folder');
	
	                //обновляем рейтинг пользователя в рутовых разделах
	                foreach ($arrTree as $arr)
	                	if ($arr['rating'])
	                		Rating::updateFolderRating($idUser, $arr['ID_folder'], $arr['rating']);
	                return $arrTree;
	        }
        }
        else{        	
          return $arrTree = self::getTreeStructure('empty');
        }
  }

  /**
   * рекурсивно обновляем(прибавляем рейтинг потомков) рейтинг родительских папок
   */
  public static function updateParrentsRating($id, $arrayKeyId, $rating){
        $id = (int)$id;//преобразуем в integer
        if (isset($arrayKeyId[$id]['ID_root_folder'])){
                $arrayKeyId[$arrayKeyId[$id]['ID_root_folder']]['rating'] += $rating;
                $arrayKeyId = self::updateParrentsRating($arrayKeyId[$id]['ID_root_folder'], $arrayKeyId, $rating);
        }
        return $arrayKeyId;
  }

  /**
   * персчет места в рутовых разделах для пользователей
   */
  public static function recountUserPlace(){
        $arrUserId = User_User::getAllUsersId();

        foreach ($arrUserId as $arrUserId){
                //получаем id папок с рейтингом и их родителей
                $arrUserRatingFolder = self::getTopFoldersByUserRating($arrUserId);

                //если рейтинг в папках есть
                if (!empty($arrUserRatingFolder)){

                        //создаем массив из папок с рейтингом
                        $arrUserRating = NULL;
                        foreach ($arrUserRatingFolder as $arr){
                                $arrUserRating[] = $arr['ID_folder'];
                                $arrUserRatingAndIDUser[$arrUserId][] = $arr['ID_folder'];
                        }

                        //получаем всё папки, нужные для построения дерева
                        $arrRatingForTreeConv = self::_baseGetFolderRatingCurUser($arrUserRatingFolder, $arrUserRating, $arrUserId,  true);

                        $size = sizeof($arrRatingForTreeConv);
                        for ($num = 0; $num < $size; $num++)
                                        $arrRatingForTreeConv[$num]['ID_user'] = $arrUserId;

                        if ($arrRatingForTreeConv){
                                //сортируем масив по возрастанию
                                sort($arrUserRating);
                                //вместо ключа задаем idfolder
                                foreach ($arrRatingForTreeConv as $arr=>$b)
                                        $arrayKeyId[$b['ID_folder']] = $b;

                                //прибавляем рейтинг потомков родительским папкам
                                foreach ($arrUserRating as $arr=>$id)
                                        $arrayKeyId = self::updateParrentsRating($id, $arrayKeyId, $arrayKeyId[$id]['rating']);

                                //удаляем не рутовые разделы
                                foreach ($arrayKeyId as $arr)
                                        if (empty($arr['ID_root_folder']))
                                                $arrayKeyIdRoot[$arr['ID_folder']][] = $arr;
                        }
                }
        }

        echo '<pre>';
        	print_r($arrayKeyIdRoot);
        echo '</pre>';

        //отправляем на сортировку по рейтингу
        foreach ($arrayKeyIdRoot as $a=>$b)
                usort($arrayKeyIdRoot[$a], array("Rating","sortRating"));

          Rating::addPlaceToRootFolder($arrayKeyIdRoot, $arrUserRatingAndIDUser);
          return true;
  }

  /**
   * получаем id папок с наибольшим рейтингом пользователя
   *
   * @return unknown
   */
  public static function getTopFoldersByUserRating($idUser){

        $objDB = Service_Database::instance();
        //получаем id 10 папок с наибольшим рейтингом пользователя
        $stmt = "
        SELECT `folder_rating`.`ID_folder`,
                                 `folder`.`parents_ids`
                FROM `folder_rating`
                LEFT JOIN `folder` ON `folder_rating`.`ID_folder` = `folder`.`ID_folder`
                WHERE `folder_rating`.`ID_user` = " . $idUser . "
                ORDER BY `folder_rating`.`rating`";
        $arrUserRating = $objDB->select($stmt);
        return $arrUserRating;
  }

  /**
   * получение рейтинга пользователя по каждому разделу
   *
   */
  private static function _baseGetFolderRatingCurUser($arrUserRatingFolder, $arrUserRating, $idUser,  $ratingRecountFlag = false){
        $objDB = Service_Database::instance();

        if (!$ratingRecountFlag)
                $fields = "
                         `folder`.`name` AS `folder_name`,
                         `folder`.`description`,
                         `folder_rating`.`place`,
                         `folder`.`children_amount`,
                         `folder`.`parents_ids`,
                         `folder`.`ID_main_root_folder`,";
        else
                $fields = '';

        if (!empty($arrUserRatingFolder)){
                //создеаем массив из id родителей папок, в которых у нас есть рейтинг
                foreach ($arrUserRatingFolder as $arrUserRatingFolder)
                        if (!empty($arrUserRatingFolder['parents_ids']))
                                $arrayParentsIDs[] = $arrUserRatingFolder['parents_ids'];

                //создаем одномерный массив c нужными рутовыми idFolder из parents_ids
                $size = isset($arrayParentsIDs) ? sizeof($arrayParentsIDs) : 0;
                for ($num = 0; $num < $size; $num++){
	                if (strstr($arrayParentsIDs[$num], ',')){
	                        $timedArray = split(', ', $arrayParentsIDs[$num]);
	                        foreach ($timedArray as $timedArray)
	                                $arrFolderIds[] = $timedArray;
	                }
	                else
	                	$arrFolderIds[] = $arrayParentsIDs[$num];
                }

                //удаляем повторяющиеся
                $arrayParentsIDs = isset($arrFolderIds) ? array_unique($arrFolderIds) : NULL;

                // удаляем пустые значения (для первых рутовых)
                $sizeArrayParentsIDs = isset($arrayParentsIDs) ? sizeof($arrayParentsIDs) : 0;
                for ($i=0; $i<$sizeArrayParentsIDs; $i++){
                        if (isset($arrayParentsIDs[$i]))
                                if ($arrayParentsIDs[$i] == NULL)
                                        unset($arrayParentsIDs[$i]);
                }

                $strParentsIDs = isset($arrayParentsIDs) ? join(', ', $arrayParentsIDs) : '';


                //создаем строчку из всех нужных нам idFolder
                $whereIn = (!empty($strParentsIDs) ? $strParentsIDs . ', ' : NULL) . join(', ', $arrUserRating);

                $stmt = '
                SELECT `folder`.`ID_folder`,
                                                 `folder`.`ID_root_folder`,' . $fields . '
                                                 `folder_rating`.`rating`
                        FROM `folder`
                        LEFT JOIN `folder_rating` ON `folder_rating`.`ID_folder` = `folder`.`ID_folder` AND
                                                                                                                                         `folder_rating`.`ID_user` = ' . $idUser . '
                        WHERE `folder`.`ID_folder` IN (' . $whereIn . ') ';
                $arrResult = $objDB->select($stmt);

                return $arrResult;
        }
        else
                return false;
  }

  /**
   * Перемещаем все вопросы из одно раздела в другой
   *
   * @param int $srcChapterId
   * @param int $dstChapterId
   * @return int - кол-во перемещённых вопросов
   */
  private static function _baseMoveFolderQuestionsToFolder($srcFolderId, $dstFolderId) {
    $objDB = Service_Database::instance();
    $stmt = "UPDATE `question`
             SET `question`.`ID_folder`='" . $dstFolderId . "'
                   WHERE `question`.`ID_folder`='" . $srcFolderId . "'";
    return $objDB->query($stmt);
  }

  /**
   * Получаем количество дочерних разделов
   *
   * @param int $ID_folder - идентификатор корневого раздела
   * @return int
   */
  private static function _getCountOfChildrenFolders(int $ID_folder) {
    $objDB = Service_Database::instance();
    $stmt = "SELECT `folder`.`children_amount`
             FROM `folder`
             WHERE `folder`.`ID_folder`='" . $ID_folder . "'";
    return $objDB->selectSimpleField($stmt);
  }

  /**
   * Увеличение счётчика сущностей раздела структуры на единицу
   *
   * @param int|array $ID_folder - идентификатор(ы) раздела
   * @return bool
   */
  public static function incrementFolderEssenceCnt($rootFoldersIDs, $essenceType) {
          $objDB = Service_Database::instance();
          $essenceType = Service_Essence::getEssenceTypeName(Service_Essence::getEssenceTypeID($essenceType));
          if (is_array($rootFoldersIDs))
            $stmtWhere = "`folder`.`ID_folder` IN ('" . join("', '", $rootFoldersIDs) . "')";
          else
            $stmtWhere = "`folder`.`ID_folder`='" . $rootFoldersIDs . "'";
          $stmt = "UPDATE `folder`
                   SET `folder`.`" . $essenceType . "_amount`=(`folder`.`" . $essenceType . "_amount`+1)
                   WHERE " . $stmtWhere;
          $objDB->query($stmt);
          return true;
  }
  public static function incrementStructureEssenceCnt($idFolder, $essenceType, $forQuestionFlag = false) {
    if (!is_NULL($idFolder) && ($idFolder != 'NULL') && ($idFolder != 'NULL')) {
      $arrParentFoldersIDs = TreeStructure::getRootFolders($idFolder, $forQuestionFlag);
      $arrParentFoldersIDs[] = $idFolder;
      self::incrementFolderEssenceCnt($arrParentFoldersIDs, Service_Essence::getEssenceTypeID($essenceType));
    }
          return true;
  }

  /**
   * Уменьшение счётчика сущностей раздела структуры на единицу
   *
   * @param int|array $ID_folder - идентификатор(ы) раздела
   * @return bool
   */
  public static function decrementFolderEssenceCnt($rootFoldersIDs, $essenceType) {
          $objDB = Service_Database::instance();
          $essenceType = Service_Essence::getEssenceTypeName(Service_Essence::getEssenceTypeID($essenceType));
          if (is_array($rootFoldersIDs))
            $stmtWhere = "`folder`.`ID_folder` IN ('" . join("', '", $rootFoldersIDs) . "')";
          else
            $stmtWhere = "`folder`.`ID_folder`='" . $rootFoldersIDs . "'";
          $stmt = "UPDATE `folder`
                   SET `folder`.`" . $essenceType . "_amount`=(`folder`.`" . $essenceType . "_amount`-1)
                   WHERE " . $stmtWhere;
          $objDB->query($stmt);
          return true;
  }
  public function decrementStructureEssenceCnt($idFolder, $essenceType, $forQuestionFlag = false) {
    if (!is_NULL($idFolder) && ($idFolder != 'NULL')) {
      $arrParentFoldersIDs = TreeStructure::getRootFolders($idFolder, $forQuestionFlag);
      $arrParentFoldersIDs[] = $idFolder;
      self::decrementFolderEssenceCnt($arrParentFoldersIDs, Service_Essence::getEssenceTypeID($essenceType));
    }
          return true;
  }

  /**
   * получение списка id всех родителей конкретной папки
   *
   * @param unknown_type $idFolder
   */
  private static function getParentsIdsInString($idFolder){
        $objDB = Service_Database::instance();
        return $objDB->selectSimpleField('SELECT `parents_ids` FROM `folder` WHERE `ID_folder` = ' . $idFolder);
  }

  /**
   * Добавление в БД нового раздела
   *
   * @param int $ID_user - идентификатор пользователя
   * @param string $name - название раздела
   * @param string $description - описание раздела
   * @param int $ID_root - идентификатор корневого раздела
   * @return int - идентифкатор добавленного раздела
   */
  private static function _baseAddFolder(int $ID_user, string $name, string $description, int $ID_root = NULL, $onlyForQuestion = false) {
    $objDB = Service_Database::instance();
    if (!$ID_root || $ID_root == 'NULL' || $ID_root == 'NULL'){
      $ID_root = NULL;
      $parentsIds = '';
    } else {
        $parentsIdsStr = self::getParentsIdsInString($ID_root);
        if ($parentsIdsStr != '')
                $parentsIds = $parentsIdsStr . ', ' . $ID_root;
        else
                $parentsIds = $ID_root;
    }
    $dateNow = Service_Date::gLocalTime2BD();
    $arrInsert = array();
    $arrInsert['ID_user'] = $ID_user;
    if ($ID_root)
        $arrInsert['ID_root_folder'] = $ID_root;
    $arrInsert['name'] = $name;
    $arrInsert['description'] = $description;
    $arrInsert['creation'] = $dateNow;
    if ($onlyForQuestion)
        $arrInsert['show_folder'] = 0;
    $arrInsert['parents_ids'] = $parentsIds;
    $addedFolderId = $objDB->insertAutoincrement('folder', $arrInsert);
    if ($ID_root)
      self::_incrementFolderChildrenCnt($ID_root);
    return $addedFolderId;
  }


  /**
   * Увеличение счётчика вложенных (дочерних) разделов структуры вопросов на единицу
   *
   * @param int $ID_folder - идентифкатор раздела
   * @return bool
   */
  private static function _incrementFolderChildrenCnt(int $ID_folder) {
          $objDB = Service_Database::instance();
          $stmt = 'UPDATE `folder`
                   SET `folder`.`children_amount`=(`folder`.`children_amount`+1)
                   WHERE `folder`.`ID_folder`=' . $ID_folder;
          $objDB->query($stmt);
          return true;
  }

//  /**
//   * Уменьшение счётчика вложенных (дочерних) разделов структуры вопросов на единицу
//   *
//   * @param int $ID_folder - идентифкатор раздела
//   * @return bool
//   */
//  private static function _decrementFolderChildrenCnt(int $ID_folder) {
//        $objDB = Service_Database::instance();
//        $stmt = 'UPDATE `folder`
//                 SET `folder`.`children_amount`=(`folder`.`children_amount`-1)
//                 WHERE `folder`.`ID_folder`=' . $ID_folder;
//        $objDB->query($stmt);
//        return true;
//  }

        /**
         * выбирает информацию о типе отображения дерева для пользователя
         *
         * @param int $idUser
         * @return bool - true, if linear, else false
         */
/*      public static function getLinearFlagForCurUser($idUser){
                $objDB = Service_Database::instance();
                $stmt = "SELECT `user`.`tree_structure_linear_flag`
                                FROM `user`
                                WHERE `user`.`ID_user`='" . $idUser . "'";
                return $objDB->selectSimpleField($stmt);
        }*/

        /**
         * изменяет тип отображения дерева для пользователя
         *
         * @param int $idUser
         * @param bool $flag - "0" - стандартно, tree  "1" - linear
         */
/*      public static function addLinearFlagToUser($idUser, $flag){
                $objDB = Service_Database::instance();
                $objDB->update('user', array('tree_structure_linear_flag' => $flag), array('ID_user' => $idUser));
        }*/

  /**
   * Получаем информацию о логическом разделе
   *
   * @param int $folderId - идентификатор раздела
   * @param bool $isFullIDOnly - получаем только ID текущего и родительского разделов
   * @return array
   */
  public static function getFolder($folderId, $isFullIDOnly = '') {
    if (!$folderId || ($folderId == 'NULL'))
      return array('ID_folder' => 0, 'ID_root_folder' => NULL, 'name' => '', 'description' => 'Начало раздела', 'children_amount' => self::getSubFoldersCnt($folderId));
    $objDB = Service_Database::instance();
    $addFields = '';
    if (empty($isFullIDOnly))
      $addFields = ', `folder`.`ID_root_folder`, `folder`.`ID_user`,
                      `folder`.`ID_main_root_folder`, `folder`.`name`, `folder`.`description`,
                      `folder`.`creation`, `folder`.`children_amount`, `folder`.`show_folder`';
    $stmt = "SELECT `folder`.`ID_folder`, `folder`.`ID_root_folder` " . $addFields . "
             FROM `folder`
             WHERE `ID_folder`='" . $folderId . "'";
//    echo $stmt;
//    die();
    return $objDB->selectOne($stmt);
  }

  /**
   * Получаем количество подразделов для раздела
   *
   * @param int $ID_root
   * @return int
   */
  public static function getSubFoldersCnt($ID_root = NULL) {
          $objDB = Service_Database::instance();
    if (!$ID_root || ($ID_root == 'NULL'))
          $stmtWhere = "ISNULL(`ID_root_folder`)";
        else
          $stmtWhere = "`ID_root_folder`='" . $ID_root ."'";
    $stmt = "SELECT COUNT(`folder`.`ID_folder`)
                   FROM `folder`
                   WHERE " . $stmtWhere;
    return $objDB->selectSimpleField($stmt);
  }

  /**
   * Получаем информацию о логических разделах в текущем разделе
   *
   * @param  int $ID_root - идентификатор текущего корневого раздела
   * @return array
   */
  public function getSubFolders($ID_root = NULL) {
          $objDB = Service_Database::instance();
    if (!$ID_root || ($ID_root == 'NULL'))
          $stmtWhere = "ISNULL(`ID_root_folder`)";
        else
          $stmtWhere = "`ID_root_folder`='" . $ID_root ."'";
    $stmt = "SELECT `folder`.`ID_folder`, `folder`.`name`,
                    `folder`.`description`, `folder`.`children_amount`,
                    `folder`.`question_amount`
                   FROM `folder`
                   WHERE " . $stmtWhere;
    return $objDB->select($stmt);
  }

  public function checkNewEssenceCanBeAdded($ID_folder) {
    if ($ID_folder && ($ID_folder != 'NULL') && (self::_getCountOfChildrenFolders($ID_folder) == 0))
      return true;
    return false;
  }

  /**
   * Получаем ID раздела "Общие вопросы для данного раздела дерева (ВО)"
   *
   * @param int $idFolder
   * @return int
   */
  public function getCommonQuestionsFolderId($idFolder) {
    $objDB = Service_Database::instance();
    if (!$idFolder || ($idFolder == 'NULL')) $stmtWhere = "ISNULL(`ID_root_folder`)";
    else $stmtWhere = "(`ID_root_folder`='" . $idFolder ."')";
    $stmtWhere .= " AND (`name`='Общие вопросы')";
    $stmt = "SELECT `folder`.`ID_folder`
             FROM `folder`
             WHERE " . $stmtWhere;
    return $objDB->selectSimpleField($stmt);
  }

  /**
   * Получаем путь к предложенному пользователями разделу
   *
   * @param array $arrChapter
   * @param string $offeredChapterName
   * @return array
   */
  public static function getOfferedFoldersPath(array $arrFolder, $offeredFolderName) {
          $arrFoldersPath = array();
    $arrFoldersPath[] = $offeredFolderName;
        $arrFoldersPath[] = $arrFolder['name'];
    while (!is_NULL($arrFolder['ID_root_folder'])) {
        $arrFolder = self::getFolder($arrFolder['ID_root_folder']);
                $arrFoldersPath[] = $arrFolder['name'];
    }
    return array_reverse($arrFoldersPath);
  }

/*



        public static function getIdFolderFromCurId($curId, $essenceType){
                $objDB = Service_Database::instance();
                switch ($essenceType){
                        case 'question':
                                $stmt = 'SELECT `ID_root'


                $stmt = "SELECT `ID_folder`";
                }
        }*/

  /**
   * Получаем путь к разделу
   *
   */
  public static function getFoldersPath(array $arrFolder, $isNamesOnly = false) { //ОПТИМИЗИРОВАТЬ
          $arrFoldersPath = array();
          if ($isNamesOnly)
          $arrFoldersPath[] = $arrFolder['name'];
        else
          $arrFoldersPath[] = array('name' => $arrFolder['name'], 'ID_folder' => $arrFolder['ID_folder']);
    while ($arrFolder['ID_root_folder']) {
        $arrFolder = self::getFolder($arrFolder['ID_root_folder']);
          if ($isNamesOnly)
          $arrFoldersPath[] = $arrFolder['name'];
        else
          $arrFoldersPath[] = array('name' => $arrFolder['name'], 'ID_folder' => $arrFolder['ID_folder']);
    }
    return array_reverse($arrFoldersPath);
  }

/**
   * Получаем информацию о родительском разделе для заданного вопроса
   */
  public function getEssenceRootFolder($essenceName, $idEssence, $isIdOnly = false) {
    $objDB = Service_Database::instance();
    $addFields = "";
    $addFrom = "";
    if (!$isIdOnly) {
      $addFields = "`folder`.`ID_root_folder`, `folder`.`ID_user`,
                    `folder`.`ID_main_root_chapter`, `folder`.`name`, `folder`.`description`,
                    `folder`.`creation`, `folder`.`children_amount`, `" . $idEssence . "_amount`";
      $addFrom = "LEFT JOIN `folder` ON `" . $essenceName . "`.`ID_folder`=`folder`.`ID_folder`";
    }
    $stmt = "SELECT `" . $essenceName . "`.`ID_folder` " . $addFields . "
             FROM `" . $essenceName . "`
             " . $addFrom . "
             WHERE `" . $essenceName . "`.`ID_" . $essenceName . "`='" . $idEssence . "'";
    if ($isIdOnly)
      return $objDB->selectSimpleField($stmt);
    return $objDB->selectOne($stmt);
  }

  /**
   * Получаем количество сущностей в разделе, для текущего пользователя (опционально)
   */
  public function getCountOfFolderEssences($essenceName, $ID_folder, $ID_user = NULL) {
    $objDB = Service_Database::instance();
    if (!$ID_folder)
      $stmtWhere = "ISNULL(`" . $essenceName . "`.`ID_folder`)";
    else
      $stmtWhere = "`" . $essenceName . "`.`ID_folder`='" . $ID_folder . "'";
    if ($ID_user)
      $stmtWhere .= " AND `" . $essenceName . "`.`ID_user`='" . $ID_user . "'";
    $stmt = "SELECT COUNT(`" . $essenceName . "`.`ID_" . $essenceName . "`) as `" . $essenceName . "Cnt`
             FROM `" . $essenceName . "`
             WHERE " . $stmtWhere;
    return $objDB->selectSimpleField($stmt);
  }


  public static function getFoldersNamesByIDs($arrIDs) {
    if (sizeof($arrIDs)==0) return array();
        $objDB = Service_Database::instance();
        $stmt = 'SELECT `folder`.`name`
                         FROM `folder`
                         WHERE `folder`.`ID_folder` IN (' . join(', ', $arrIDs) . ')';
    return $objDB->selectSimpleArray($stmt);
  }

  public static function getRootFolders($idFolder, $forQuestionFlag = false) {
        $objDB = Service_Database::instance();
        $stmt = 'SELECT `folder`.`parents_ids`
                         FROM `folder`
                         WHERE `folder`.`ID_folder` = "' . $idFolder . '"';
        if (!$forQuestionFlag)
        $stmt .= ' AND show_folder = 1';
        $strParentIDs = $objDB->selectSimpleField($stmt);
        if (empty($strParentIDs))
          return array();
        return explode(', ', $strParentIDs);

/*        $arrRootFoldersIDs = array();
    if ($arrFolder['ID_folder'])
      $arrRootFoldersIDs[] = $arrFolder['ID_folder'];
    while ($arrFolder['ID_root_folder']) {
        $arrFolder =  self::getFolder($arrFolder['ID_root_folder'], 'ID_folder');
          $arrRootFoldersIDs[] = $arrFolder['ID_folder'];
    }
    return array_reverse($arrRootFoldersIDs);*/
  }

  public static function getChildrenFolders($arrFoldersIds, $forQuestionFlag = false){
        if (is_array($arrFoldersIds) && sizeof($arrFoldersIds) == 0)
                return array();
        if (!is_array($arrFoldersIds) && !is_int($arrFoldersIds))
                return array();
        if (!is_array($arrFoldersIds)){
                $id = $arrFoldersIds;
                $arrFoldersIds = array();
                $arrFoldersIds[0] = $id;
        }
        $objDB = Service_Database::instance();
        $stmt = 'SELECT ID_folder
                        FROM folder_parent_id
                        WHERE ID_root_folder IN (' . join(', ', $arrFoldersIds) . ')';
        if (!$forQuestionFlag)
                $stmt .= ' AND show_folder = 1';
/*              $st = 'SELECT `tutorial_lesson`.`ID_tutorial_lesson`, `tutorial`.`name`, `tutorial`.`url_name`
                FROM `tutorial_lesson`
                LEFT JOIN `tutorial_theme`
                ON `tutorial_theme`.`ID_tutorial_theme` = `tutorial_lesson`.`ID_tutorial_theme`
                LEFT JOIN `tutorial`
                ON `tutorial`.`ID_tutorial` = `tutorial_theme`.`ID_tutorial`
                WHERE `tutorial`.`ID_folder` = ';*/
                        $arrReturn = $objDB->selectSimpleArray($stmt);
                if (isset($arrReturn))
                        return array_unique($arrReturn);
                else
                        return $arrReturn;
//      return arrayConvert($objDB->select($stmt), 'ID_root_folder', array('ID_folder'), 'arrChildren');
  }

  /**
   * получаем потомков папок
   */
  public static function getVisibleChildrensForIndex($arr){
  	$objDB = Service_Database::instance();
  	$stmt = "
  	SELECT `ID_folder`, `name`, `ID_root_folder`
  	FROM `folder`
  	WHERE `folder`.`ID_root_folder` IN(" . join(', ' , $arr) . ") AND `show_folder` = 1
  	ORDER BY `users_count`";
  	return $objDB->select($stmt);
  }

  public static function addChildrenForFolder($idNewFolder, $showFolderFlag = true){
        $arrRootIds = self::getRootFolders($idNewFolder, true);
        foreach ($arrRootIds as $rootId)
                self::_baseAddChildrenForFolder($rootId, $idNewFolder, $showFolderFlag);
  }

  private static function _baseAddChildrenForFolder($idFolder, $idChildrenFolder, $showFolderFlag = true){
        $objDB = Service_Database::instance();
        $arrInsert = array('ID_folder' => $idChildrenFolder, 'ID_root_folder' => $idFolder);
        if ($showFolderFlag)
                $arrInsert['show_folder'] = 1;
        else
                $arrInsert['show_folder'] = 0;
        $objDB->insert('folder_parent_id', $arrInsert);
  }

  public static function getFolderLinearStatus($idUser, $idFolder){
        $objDB = Service_Database::instance();
        return $objDB->isRecordExist('SELECT ID_folder FROM users_folders WHERE ID_user = ' . $idUser . ' AND ID_folder = ' . $idFolder . ' LIMIT 1') ? 1 : 0;
  }

  public static function getFolderNamesByIds($arrIds){
        $objDB = Service_Database::instance();
        return $objDB->select('SELECT ID_folder, name FROM folder WHERE ID_folder IN (' . join(', ', $arrIds) . ')');
  }

  public static function editCheck($essenceType){
        return preg_replace('/(_edit)/', '', $essenceType);
  }

        public static function getFolderName($idFolder){
                $arrFolderInfo = self::getFolderInfo($idFolder);
                if (isset($arrFolderInfo['name']))
                        return $arrFolderInfo['name'];
                else return '';
        }

        public static function setUsersCountForFolder($idFolder, $increment = true){
                $objDB = Service_Database::instance();
                if ($increment)
                        $count = '+1';
                else $count = '-1';
          $stmt = 'UPDATE `folder`
                   SET `folder`.`users_count`=(`folder`.`users_count`' . $count . ')
                   WHERE `folder`.`ID_folder`=' . $idFolder;
          $objDB->query($stmt);
          return true;
        }


 public static function getArrayOfRootFolders(){
 	$objDB = Service_Database::instance();
 	$stmt = 'SELECT ID_folder, name as folder_name
 					FROM folder
 					WHERE ID_root_folder IS NULL';
 	return $objDB->select($stmt);
 }

 /*Проверяет папку дерева на существование*/
 public static function checkIfFolderExists($idFodler) {
  if (empty($idFodler) || ($idFodler <= 0))
    return false;
  $objDB = Service_Database::instance();
 	$stmt = 'SELECT ID_folder
 					 FROM folder
 					 WHERE ID_folder=' . $idFodler;
 	return $objDB->isRecordExist($stmt);
 }

 /**
  * получаем линейный список всех папок
  */
 public static function getLinearAllFolder(){
 	$objDB = Service_Database::instance();
 	$stmt = 'SELECT `ID_folder`, `ID_root_folder`
 					FROM `folder`';
 	return $objDB->select($stmt);

 }

 /**
  * весь пересчет кол-ва сущностей в папках
  *
  */
 public function recountEssencesInTree(){
 	$tutorialJoin = 'LEFT JOIN `tutorial_theme` ON `tutorial_lesson`.`ID_tutorial_theme`=`tutorial_theme`.`ID_tutorial_theme`';
 	$tutorialJoin .= 'LEFT JOIN `tutorial` ON `tutorial_theme`.`ID_tutorial`=`tutorial`.`ID_tutorial`';
 	$this->recountEssenceInTree('article', 'article', '`article`.`ID_essence`', '`article`.`draft` = 0 AND `article`.`delete_flag` = 1 AND `article`.`essence_type` = 11');
  $this->recountEssenceInTree('solution', 'solution', '`solution`.`ID_folder`');
 	$this->recountEssenceInTree('question', 'question', '`question`.`ID_folder`');
 	$this->recountEssenceInTree('content_request', 'content_request', '`content_request`.`ID_folder`');
 	$this->recountEssenceInTree('tutorial_lesson', 'tutorial_lesson', '`tutorial`.`ID_folder`', '', $tutorialJoin);
 	$this->recountEssenceInTree('tutorial_lesson', 'tutorial_lesson', '`tutorial`.`ID_folder`', '', $tutorialJoin);
 	$this->recountEssenceInTree('users_folders', 'user', '`users_folders`.`ID_folder`');
	echo 'Пересчет прошел успешно';

 }

   /**
   * пересчет кол-ва сущностей в папках
   *
   */
  public function recountEssenceInTree($folder, $essence, $mainField, $where = NULL, $join = NULL){
  	switch ($essence){
  		case 'tutorial_lesson': $amountField = 'tutorial_amount'; break;
  		case 'user': $amountField = 'users_count'; break;
  		default: $amountField = $essence . '_amount';
  	}

  	$objDB = Service_Database::instance();
  	//получаем кол-во статей в каждом разделе
  	$stmt = "
  	SELECT COUNT(`" . $folder . "`.`ID_" . $essence . "`) as `count`,
  							 " . $mainField . " as `ID_folder`
  	FROM `" . $folder . "`
  	" . ($join ? $join : '') . "
  	" . ($where ? "WHERE " . $where : '') . "
  	GROUP BY " . $mainField;
  	$arrEssence = $objDB->select($stmt);

  	/*
  	!!!!!!!!!!!!!!
  	//echo $stmt;
  	echo '<pre>';
  		print_r($arrEssence);
  	echo '</pre>!';
  	!!!!!!!!!!!*/

  	//создаем массив для пересчета
  	foreach ($arrEssence as $folder)
  		$update[] = array(0=>$folder['ID_folder'], 1=>$folder['count']);

  	//рекурсивно прибавляем родителям
  	$objTreeStructure = new TreeStructure();
  	$objTreeStructure->recountSmth($update);
  	//берем полученный массив
    $arrFoldersEssence = $objTreeStructure->arrFolders;

    //преобразуем к нужному виду
    foreach ($arrFoldersEssence as $folder)
    	$arrUpdate[] = array(0=>$folder['ID_folder'], 1=>$folder['count']);
    /*
  	!!!!!!!!!!!!!!
  	echo '<pre>';
    	print_r($arrUpdate);
    echo '</pre>-------------------------------------------------------';
    !!!!!!!!!!!!!!*/
    Service_Database::updateFewRecord('folder', $amountField, 'ID_folder', $arrUpdate);
  }

 /**
  * рекурсивный пересчет чего либо в дереве
  *
  * @param array $arr типа array(0=>array(0=>ID_folder_1, 1=>кол-во), 1=>array(0=>ID_folder_2, 1=>кол-во))
  */
 public function recountSmth($arr){
 	$arrAllFolder = TreeStructure::getLinearAllFolder();
 	foreach ($arrAllFolder as $folder)
 		$this->arrFolders[$folder['ID_folder']] = array('ID_folder'=>$folder['ID_folder'], 'ID_root_folder'=>$folder['ID_root_folder'], 'count'=>0);
 	foreach ($arr as $folder)
	 	$this->_recountSmth($folder[0], $folder[1]);
 }

 /**
  * инкремируем папку и родителей
  *
  */
 private function _recountSmth($idFolder, $count){
 	$this->arrFolders[$idFolder]['count'] += $count;
 	if ($this->arrFolders[$idFolder]['ID_root_folder'])
 		$this->_recountSmth($this->arrFolders[$idFolder]['ID_root_folder'], $count);
 }





////////////////////////////////////////////////////////////////// NEW AND OLD FOR neftemagnat.COM ///////////////////////////////////////////////////////////////////////

        public static function getTreeStructure($essenceType, $linearFlag = false, $idUser = NULL, $linearForCurFoldersInArray = false, $arrCurFoldersIds = array()){
                $objDB = Service_Database::instance();
                // получаем название модуля, в котором используются разделы
                $essenceTypeName = Service_Essence::getEssenceTypeName($essenceType);
                // получаем id этого модуля
                $essenceId = (int)Service_Essence::getEssenceTypeID($essenceType);
                // получаем название поля id модуля
                $idFieldName = Service_Essence::getEssenceIdFieldName($essenceType);
                // получаем название таблицы со структурой для модуля
                $tableStructureName = DB_PREFIX . $essenceTypeName."_section";
                $tableName = DB_PREFIX . $essenceTypeName;
                
                // получаем пользователя
				$objSession = User_Session::instance();
				$idUser = $objSession->getUserId();
				$idUser = $idUser ? $idUser : 0;
                
                				
                $stmt = "SELECT `$tableStructureName`.`id_section`, `$tableStructureName`.`id_root_section`, `$tableStructureName`.`name`,
                                `$tableStructureName`.`id_main_root_section`, `$tableStructureName`.`children_amount`, `$tableStructureName`.`parents_ids`
                         FROM `$tableStructureName`       
                         ORDER BY `name`";
/*                switch ($essenceType){
                        case "question":
                                $stmt .= ", `folder`.`" . $tableName . "_amount`, `folder`.`question_amount` FROM `folder`"; break;
                        case "solution":
                                $stmt .= ", `folder`.`" . $tableName . "_amount`
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                        case "tutorial":
                                $stmt .= ", `folder`.`" . $tableName . "_amount`, `tutorial`.`ID_tutorial`, `tutorial`.`name`, `tutorial`.`url_name`
                                                FROM `folder`
                                                LEFT JOIN `tutorial`
                                                ON `tutorial`.`ID_folder` = `folder`.`ID_folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                        case "programming_language":
                                $stmt .= ", `folder`.`" . $tableName . "_amount`, `programming_language`.`ID_language` AS `ID_programming_language`, `programming_language`.`language` AS `name`
                                                FROM `folder`
                                                LEFT JOIN `folder_link_language`
                                                ON `folder_link_language`.`ID_folder` = `folder`.`ID_folder`
                                                LEFT JOIN `programming_language`
                                                ON `programming_language`.`ID_language` = `folder_link_language`.`ID_language`

                                                WHERE `folder`.`show_folder` = 1"; break;
                        case "community":
                                $stmt .= "
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                        case "article":
                                $stmt .= ", `folder`.`" . $tableName . "_amount`
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                        case "content_request":
                        				$stmt .= ", `folder`.`" . $tableName . "_amount`
                                                FROM `folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                        case "empty":
                        				$stmt .= "      FROM `folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                        default:
                                $stmt .= ", `$tableName`.`$idFieldName`, `$tableName`.`name`
                                                FROM `$tableStructureName`
                                                LEFT JOIN `" . $tableName . "`
                                                ON `" . $tableName . "`.`ID_folder` = `folder`.`ID_folder`
                                                WHERE `folder`.`show_folder` = 1"; break;
                }
                if ($linearFlag){
                        if (!$linearForCurFoldersInArray)
                                $arrFoldersIds = TreeStructure::getLinearFoldersListCurUser($idUser);
                        else
                                $arrFoldersIds = $arrCurFoldersIds;
                        if (sizeof($arrFoldersIds) == 0)
                                return array('arr_folder' => array(), 'folder_size' => 0);
                        if ($essenceType == 'question')
                                $stmt .= ' WHERE `folder`.`ID_folder` IN ("' . join('", "', $arrFoldersIds) . '")';

                        else
                                $stmt .= ' AND `folder`.`ID_folder` IN ("' . join('", "', $arrFoldersIds) . '")';
                }*/


                $arrStructureFromDB = $objDB->select($stmt);
                $size = sizeof($arrStructureFromDB);
                for ($i = 0; $i < $size; $i++){
                        $arrStructureFromDB[$i]['parents_ids'] = explode(', ', $arrStructureFromDB[$i]['parents_ids']);
                }
/*                switch ($essenceTypeName){
                        case 'question':
                                $arrStructureFromDB = $arrStructureFromDB; break;
//                              $arrFolderFromDB = self::convertArrayForQuestion($arrFolderFromDB); break;
                        case 'solution':{
                                $arrStructureFromDB = $arrStructureFromDB;
                        } break;
                        case 'tutorial':{
                                $arrFields = array(0 => 'ID_tutorial', 1 => 'name', 2 => 'url_name');
                                $arrStructureFromDB = arrayConvert($arrStructureFromDB, 'ID_folder', $arrFields, 'array_tutorial');
                        } break;
                        case 'content_request':
                                $arrStructureFromDB = $arrStructureFromDB; break;
                        default:{
                                $arrFields = array(0 => 'id_' . $essenceTypeName, 1 => 'name');
                                $arrStructureFromDB = arrayConvert($arrStructureFromDB, 'id_structure', $arrFields, 'array_' . $essenceTypeName);
                        } break;
                }*/
                //$structureSize = sizeof($arrStructureFromDB);
/*              echo '<pre>';
                //echo $stmt;

                print_r($arrFolderFromDB);
                echo '</pre>';*/
                if ($linearFlag)
                        return array('arr_folder' => $arrStructureFromDB, 'folder_size' => $folderSize);
                $arrFolder = Service_ArrayConverter::convertToTreeArray($arrStructureFromDB, 'id_section', 'id_root_section');
                return $arrFolder;
                //return array('arr_section' => $arrFolder, 'folder_size' => $folderSize);
        }
}
?>